import gdata.docs.service
from urlparse import *
import httplib
import urllib2
import os

class ProxyHTTPConnection(httplib.HTTPConnection):

        _ports = {'http' : 80, 'https' : 443}

        def request(self, method, url, body=None, headers={}):
                #request is called before connect, so can interpret url and get
                #real host/port to be used to make CONNECT request to proxy
                proto, rest = urllib.splittype(url)
       
                if proto is None:
                        raise ValueError, "unknown URL type: %s" % url
                #get host
                host, rest = urllib.splithost(rest)
                #try to get port
                host, port = urllib.splitport(host)
                #if port is not defined try to get from proto
                if port is None:
                        try:
                                port = self._ports[proto]
                        except KeyError:
                                raise ValueError, "unknown protocol for: %s" % url
                self._real_host = host
                self._real_port = port
                httplib.HTTPConnection.request(self, method, url, body, headers)

        def connect(self):
                httplib.HTTPConnection.connect(self)
       
                # Modified by Devraj Mukherjee to add authentication support basic auth
                #send proxy CONNECT request
                extra_string = "CONNECT %s:%s HTTP/1.0\r\n" % (self._real_host, self._real_port)
                extra_string += self._get_authentication_string() + "\r\n"
                self.send(extra_string)

                #expect a HTTP/1.0 200 Connection established
                response = self.response_class(self.sock, strict=self.strict, method=self._method)
                (version, code, message) = response._read_status()
                #probably here we can handle auth requests...
                if code != 200:
                        #proxy returned and error, abort connection, and raise exception
                        self.close()
                        raise socket.error, "Proxy connection failed: %d %s" % (code, message.strip())
                #eat up header block from proxy....
                while True:
                        #should not use directly fp probablu
                        line = response.fp.readline()
                        if line == '\r\n': break
               
        def _get_authentication_string(self):
                auth_string = ""
                proxy_username = os.environ.get("proxy-username")
                proxy_password = os.environ.get("proxy-password")
                if proxy_username and proxy_password:
                        encoded_user_pass = base64.encodestring("%s:%s" % (proxy_username, proxy_password))
                        auth_string = "Proxy-authorization: Basic %s\r\n" % encoded_user_pass
               
                return auth_string
class ProxyHTTPSConnection(ProxyHTTPConnection):
       
        default_port = 443

        def __init__(self, host, port = None, key_file = None, cert_file = None, strict = None):
                ProxyHTTPConnection.__init__(self, host, port)
                self.key_file = key_file
                self.cert_file = cert_file
        def connect(self):
                ProxyHTTPConnection.connect(self)
                #make the sock ssl-aware
                ssl = socket.ssl(self.sock, self.key_file, self.cert_file)
                self.sock = httplib.FakeSocket(self.sock, ssl)
class ConnectHTTPHandler(urllib2.HTTPHandler):


        def __init__(self, proxy=None, debuglevel=0):
                self.proxy = self._parse_proxy_details(proxy)
                urllib2.HTTPHandler.__init__(self, debuglevel)

        def do_open(self, http_class, req):
                if self.proxy is not None:
                        req.set_proxy(self.proxy, 'http')
                return urllib2.HTTPHandler.do_open(self, ProxyHTTPConnection, req)

        def _parse_proxy_details(self, proxy_string):
                proto, rest = urllib.splittype(proxy_string)
                host,  rest = urllib.splithost(rest)
                host,  port = urllib.splitport(host)
                return "%s:%s" % (host, port)
class ConnectHTTPSHandler(urllib2.HTTPSHandler):

        def __init__(self, proxy=None, debuglevel=0):
                self.proxy = self._parse_proxy_details(proxy)
                urllib2.HTTPSHandler.__init__(self, debuglevel)

        def do_open(self, http_class, req):
                if self.proxy is not None:
                        req.set_proxy(self.proxy, 'https')
                return urllib2.HTTPSHandler.do_open(self, ProxyHTTPSConnection, req)
       
        def _parse_proxy_details(self, proxy_string):
                proto, rest = urllib.splittype(proxy_string)
                host,  rest = urllib.splithost(rest)
                host,  port = urllib.splitport(host)
                return "%s:%s" % (host, port)  

SPREADSHEET_FORMATS=['csv','tsv','ods','tab','xls']
PRESENTAION_FORMATS=['ppt','pps']
DOCUMENT_FORMATS=['doc','odt','rtf','sxw','txt','htm','html']
mimes={'csv': 'text/csv', 'tsv': 'text/tab-separated-values','tab': 'text/tab-separated-values', 'doc': 'application/msword','ods': 'application/x-vnd.oasis.opendocument.spreadsheet','odt': 'application/vnd.oasis.opendocument.text', 'rtf': 'application/rtf','sxw': 'application/vnd.sun.xml.writer', 'txt': 'text/plain','xls': 'application/vnd.ms-excel', 'ppt': 'application/vnd.ms-powerpoint','pps': 'application/vnd.ms-powerpoint', 'htm': 'text/html', 'html' : 'text/html'}
DOCUMENT_QUERY="http://docs.google.com/MiscCommands?command=saveasdoc&docID=%s&exportformat=%s"
SPREADSHEET_QUERY="http://spreadsheets.google.com/pub?key=%s&output=%s"

class sink:
    name="Google Docs"
    files=[]
    _cookie_jar = None
    _user_agent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.6 (Ubuntu-feisty)"
    def __init__(self,config):
        print "logging in to Google Docs"
        self.gd_client = gdata.docs.service.DocsService()
        self.gd_client.email = config['username']
        self.gd_client.password = config['password']
        self.gd_client.source = 'Document List Python Sample'
        self.gd_client.ProgrammaticLogin()
        print "logged in."
        self.config=config
    def get_files(self):
        files=[]
        for entry in self.gd_client.GetDocumentListFeed().entry:
            files.append({'content.%s'%self.config['format']:self.get_file(self.get_document_id(entry.GetAlternateLink().href),self.config['format']),'id':self.get_document_id(entry.GetAlternateLink().href),'author':entry.author,'updated':entry.updated.text,'published':entry.published.text,'title':entry.title.text,'format':self.config['format']})
        return files
    def get_document_id(self, alternate_link):
        parsed_url = urlparse(alternate_link)
        url_params = parsed_url[4]
        document_id = url_params.split('=')[1]
        return document_id
    def get_file(self,id,format):
        if format in DOCUMENT_FORMATS or format in PRESENTATION_FORMATS:
            url=DOCUMENT_QUERY%(id,format)
        elif format in SPREADSHEET_FORMATS:
            url=SPREADSHEET_QUERY%(id,format)
        return self._open_https_url(url, post_data = None).read()
    def _open_https_url(self, target_url, post_data = None):
            # Opener will be assigned to either a proxy enabled or disabled opener
            opener    = None
            proxy_url = os.environ.get('http_proxy')
            
            if proxy_url:
                    opener = urllib2.build_opener(ConnectHTTPHandler(proxy = proxy_url), ConnectHTTPSHandler(proxy = proxy_url), urllib2.HTTPCookieProcessor(self._cookie_jar))
            else:
                    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self._cookie_jar))

            # Proxy or not, add the headers and place the POST reuqest
            opener.addheaders = [('User-agent', self._user_agent)]
            
            response = None
            if post_data:
                    response = opener.open(target_url, urllib.urlencode(post_data))
            else:
                    response = opener.open(target_url)
                    
            return response
    def create(self,file):
        ms = gdata.MediaSource(file['content'], mimes[file['format']], len(file['content']), "WHATCHU TALKIN 'BOUT WILLIS?", file['title'])
        if file['format'] in SPREADSHEET_FORMATS:
            entry = self.gd_client.UploadSpreadsheet(ms, file['title'])
        elif file['format'] in PRESENTAION_FORMATS:
            entry = self.gd_client.UploadPresentation(ms, file['title'])
        elif file['format'] in DOCUMENT_FORMATS:
            entry = self.gd_client.UploadDocument(ms, file['title'])
    def remove(self,source_file):
        return